package hkust.csit5110.android;

import hkust.csit5110.android.util.AndConstants;
import hkust.csit5110.android.util.GetFeatures;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.ContentBody;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;

import android.app.Activity;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

public class MatchtView extends Activity {

  private ImageView start1, end1, start2, end2, start3, end3, start4, end4, start5, end5;
  private Button button1, button2, button3, button4, button5;
  private MediaPlayer mymediaplayer = new MediaPlayer();
  private List<Map<String, String>> keyIpMapList = new ArrayList<Map<String, String>>();
  private View currPlay, currStop;

  public static int getViewIndex(View v) {
    int index = 0;
    String a = v.getContentDescription().toString();
    index = Integer.valueOf(a);
    return index;
  }

  /**
   * download the match voice with index from GAE;
   * 
   * @param index
   */
  private void downloadVoice(int index, String downloadPath) {
    Log.i("===hkust===","downPath"+downloadPath);
    if(keyIpMapList==null){
      Log.e("===hkust===","keyIpMapList is NULL!!!");
    }
    Map<String, String> keyIpMap = keyIpMapList.get(index);
    if(keyIpMap==null){
      Log.e("===hkust===","keyIpMap is NULL!!!");
    }
    String key = keyIpMap.get(AndConstants.GAE_KEY);
    if(key==null){
      Log.e("===hkust===","key is NULL!!!");
    }
    try {
      String downloadUrl = AndConstants.VOICE_URL + key;
      Log.i("===hkust===","downUrl:"+downloadUrl);
      URL url = new URL(downloadUrl);
      HttpURLConnection conn = (HttpURLConnection) url.openConnection();
      conn.setRequestMethod("GET");
      conn.setDoOutput(true);
      conn.connect();
      FileOutputStream out = new FileOutputStream(new File(downloadPath));
      InputStream in = conn.getInputStream();
      byte[] buffer = new byte[1024];
      int len = 0;
      while ((len = in.read(buffer)) > 0) {
        out.write(buffer, 0, len);
      }
      out.close();
      in.close();
    } catch (Exception e) {
      Log.e("===hkust===downloadVoice", e.getMessage());
      e.printStackTrace();
    }
  }

  OnClickListener startClick = new OnClickListener() {
    @Override
    public void onClick(View v) {
      try {
        
        if (currPlay != null) {
          currPlay.setBackgroundResource(R.drawable.play_50_thumb);
        }
        if (currStop != null) {
          currStop.setBackgroundResource(R.drawable.stop_50_thumb);
        }
        currPlay = v;
        v.setBackgroundResource(R.drawable.play_disable_thumb);
        
        int index = MatchtView.getViewIndex(v);
        mymediaplayer.reset();
        File SDCardpath = Environment.getExternalStorageDirectory();
        String matchVoicePath = SDCardpath.getAbsolutePath() + AndConstants.VOICE_DIR + AndConstants.DOWNLOAD_FILE;
        Log.i("===hkust==","start download voice");
        downloadVoice(index, matchVoicePath);
        Log.i("===hkust==","download voice finish, play");
        mymediaplayer.setDataSource(matchVoicePath);
        mymediaplayer.prepare();
        mymediaplayer.start();
      } catch (IllegalArgumentException e) {
        Log.e("===hkust===clieckStart", e.getMessage());
        e.printStackTrace();
      } catch (IllegalStateException e) {
        Log.e("===hkust===clieckStart", e.getMessage());
        e.printStackTrace();
      } catch (IOException e) {
        Log.e("===hkust===clieckStart", e.getMessage());
        e.printStackTrace();
      }
    }
  };

  OnClickListener endClick = new OnClickListener() {
    @Override
    public void onClick(View v) {
      
      if (currPlay != null) {
        currPlay.setBackgroundResource(R.drawable.play_50_thumb);
      }
      if (currStop != null) {
        currStop.setBackgroundResource(R.drawable.stop_50_thumb);
      }
      currStop = v;
      v.setBackgroundResource(R.drawable.stop_disable_thumb);
       
      Log.i("===hkust===","stop voice");
      mymediaplayer.stop();
      mymediaplayer.reset();
    }
  };

  /**
   * click "chat" from match list view to chat view
   */
  OnClickListener chatClick = new OnClickListener() {
    @Override
    public void onClick(View v) {
      int index = MatchtView.getViewIndex(v);
      Map<String, String> keyIpMap = keyIpMapList.get(index);
      String chatIP = keyIpMap.get(AndConstants.GAE_IP);
      Log.i("===hkust===","get chat IP:"+chatIP);
      Intent intent = new Intent(MatchtView.this, ChatView.class);
      intent.putExtra(AndConstants.GAE_IP, chatIP);
      Log.i("===hkust===","change to chat activity");
      startActivity(intent);
    }
  };

  @Override
  public void onCreate(Bundle savedInstanceState) {
    try {
      Log.i("===hkust===", "Enter Match Voice List,get match List");
      this.getMatchVoiceList();
    } catch (Exception e1) {
      Log.e("===hkust===", e1.getMessage());
      e1.printStackTrace();
    }
    super.onCreate(savedInstanceState);
    setContentView(R.layout.interface3);
    Log.i("===hkust===", "Find View By Id");
    start1 = (ImageView) (findViewById(R.id.start1));
    end1 = (ImageView) findViewById(R.id.end1);
    start2 = (ImageView) (findViewById(R.id.start2));
    end2 = (ImageView) findViewById(R.id.end2);
    start3 = (ImageView) (findViewById(R.id.start3));
    end3 = (ImageView) findViewById(R.id.end3);
    start4 = (ImageView) (findViewById(R.id.start4));
    end4 = (ImageView) findViewById(R.id.end4);
    start5 = (ImageView) (findViewById(R.id.start5));
    end5 = (ImageView) findViewById(R.id.end5);
    button1 = (Button) findViewById(R.id.button1);
    button2 = (Button) findViewById(R.id.button2);
    button3 = (Button) findViewById(R.id.button3);
    button4 = (Button) findViewById(R.id.button4);
    button5 = (Button) findViewById(R.id.button5);

    Log.i("===hkust===", "Set ON Click Listener");
    start1.setOnClickListener(startClick);
    start2.setOnClickListener(startClick);
    start3.setOnClickListener(startClick);
    start4.setOnClickListener(startClick);
    start5.setOnClickListener(startClick);
    start1.setContentDescription("0");
    start2.setContentDescription("1");
    start3.setContentDescription("2");
    start4.setContentDescription("3");
    start5.setContentDescription("4");

    end1.setOnClickListener(endClick);
    end2.setOnClickListener(endClick);
    end3.setOnClickListener(endClick);
    end4.setOnClickListener(endClick);
    end5.setOnClickListener(endClick);

    button1.setOnClickListener(chatClick);
    button2.setOnClickListener(chatClick);
    button3.setOnClickListener(chatClick);
    button4.setOnClickListener(chatClick);
    button5.setOnClickListener(chatClick);
    button1.setContentDescription("00");
    button2.setContentDescription("01");
    button3.setContentDescription("02");
    button4.setContentDescription("03");
    button5.setContentDescription("04");
  }

  /**
   * use the recorded voice and send to gae get match list
   * 
   * @throws Exception
   */
  private void getMatchVoiceList() throws Exception {
    /* 1.first ask gae generate a bolb key link for upload */
    String url = AndConstants.BLOB_URL;
    String uploadUrl = this.getGaeUploadUrl(url);
    uploadUrl = uploadUrl.replace("squeeze5930", "143.89.208.23");
    /* 2. post record voice to gae */
    File SDCardpath = Environment.getExternalStorageDirectory();
    File recordFile = new File(SDCardpath.getAbsolutePath() + AndConstants.VOICE_DIR + AndConstants.RECORD_FILE);
    HttpClient httpClient = new DefaultHttpClient();
    HttpPost httpPost = new HttpPost(uploadUrl);

    MultipartEntity httpEntity = new MultipartEntity();
    ContentBody contentBody = new FileBody(recordFile);
    httpEntity.addPart(AndConstants.GAE_VOICE, contentBody);
    httpEntity.addPart(AndConstants.GAE_IP, new StringBody(AndConstants.getLocalIpAddress()));
    httpClient.getParams().setParameter(AndConstants.GAE_IP, AndConstants.getLocalIpAddress());
    GetFeatures feature = new GetFeatures(recordFile.getAbsolutePath());
    httpEntity.addPart(AndConstants.GAE_ORG_VOICE, new StringBody(feature.getVoice()));
    httpEntity.addPart(AndConstants.GAE_ORG_EMOTION, new StringBody(feature.getEmotion()));
    httpEntity.addPart(AndConstants.GAE_ORG_GENDER, new StringBody(feature.getGender()));
    httpEntity.addPart(AndConstants.GAE_TAR_VOICE, new StringBody(feature.getTargetVoice()));
    httpEntity.addPart(AndConstants.GAE_TAR_EMOTION, new StringBody(feature.getTargetEmotion()));
    httpEntity.addPart(AndConstants.GAE_TAR_GENDER, new StringBody(feature.getTargetGender()));
    /*
    httpClient.getParams().setParameter(AndConstants.GAE_ORG_VOICE, feature.getVoice());
    httpClient.getParams().setParameter(AndConstants.GAE_ORG_EMOTION, feature.getEmotion());
    httpClient.getParams().setParameter(AndConstants.GAE_ORG_GENDER, feature.getGender());
    httpClient.getParams().setParameter(AndConstants.GAE_TAR_VOICE, feature.getTargetVoice());
    httpClient.getParams().setParameter(AndConstants.GAE_TAR_EMOTION, feature.getTargetEmotion());
    httpClient.getParams().setParameter(AndConstants.GAE_TAR_GENDER, feature.getTargetGender());
*/
    httpPost.setEntity(httpEntity);

    HttpResponse httpResponse;
    try {
      httpResponse = httpClient.execute(httpPost);
      InputStream is = httpResponse.getEntity().getContent();
      String strJson = this.read(is);
      Log.i("===hkust===","server response gson:"+strJson);
      Gson gson = new Gson();
      List<Map<String, String>> tempObj = gson.fromJson(strJson, new TypeToken<List<Map<String, String>>>() {
      }.getType());
      keyIpMapList = tempObj;
    } catch (Exception e) {
      Log.e("===hkust===getMatchVoiceList", e.getMessage());
      e.printStackTrace();
    }
  }

  public String getGaeUploadUrl(String url) {
    HttpClient httpclient = new DefaultHttpClient();
    HttpGet request = new HttpGet(url);
    request.addHeader("Accept", "text/plain");
    String result = "non";
    HttpResponse response = null;
    InputStream instream = null;
    try {
      response = httpclient.execute(request);
    } catch (ClientProtocolException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
    HttpEntity entity = response.getEntity();
    try {
      instream = entity.getContent();
    } catch (IllegalStateException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
    result = read(instream);
    httpclient.getConnectionManager().shutdown();
    return result;
  }

  private String read(InputStream instream) {
    StringBuilder sb = null;
    try {
      sb = new StringBuilder();
      BufferedReader r = new BufferedReader(new InputStreamReader(instream));
      for (String line = r.readLine(); line != null; line = r.readLine()) {
        sb.append(line);
      }
      instream.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
    return sb.toString();
  }

}
